'''
Cannot create dynamically in Java (at least easily): generate classes from python schema
serialyze in python by subclassing to_json: include all props
back from json:??? few data (GUI) ==> no real object necessary??
Pattern: config: get an object, modify, send it back; generate a form/template for an object; regenerate without touching modifications??
Created on Jul 20, 2009
@author: ca3jmaupas
'''
from django.utils import simplejson
json=simplejson

class a(object):
    A=1
    def __init__(self,b):
        self.d=b

o=a(9)
# doesnt work
#print simplejson.loads(a(9))
#o.__dict__.update(d)
 
# class_to_dict    
def todict(obj, classkey=None):
    if isinstance(obj, dict):
        for k in obj.keys():
            obj[k] = todict(obj[k], classkey)
        return obj
    elif hasattr(obj, "__iter__"):
        return [todict(v, classkey) for v in obj]
    elif hasattr(obj, "__dict__"):
        data = dict([(key, todict(value, classkey)) 
            for key, value in obj.__dict__.iteritems() 
            if not callable(value) and not key.startswith('_')])
        if classkey is not None and hasattr(obj, "__class__"):
            data[classkey] = obj.__class__.__name__
        return data
    else:
        return obj


class MyDecoder(json.JSONDecoder):
    
    def __init__(self):
        json.JSONDecoder.__init__(self, object_hook=self.dict_to_object)

    def dict_to_object(self, d):
        if '__class__' in d:
            class_name = d.pop('__class__')
            module_name = d.pop('__module__')
            module = __import__(module_name)
            #print 'MODULE:', module
            class_ = getattr(module, class_name)
            #print 'CLASS:', class_
            args = dict( (key.encode('ascii'), value) for key, value in d.items())
            #print 'INSTANCE ARGS:', args
            inst = class_(**args)
        else:
            inst = d
        return inst


def props(obj):
    pr = {}
    for name in dir(obj):
        value = getattr(obj, name)
        if not name.startswith('__') and not callable(value):
            pr[name] = value
    return pr

class MyEncoder(json.JSONEncoder):
    
    def default(self, obj):
        # Convert objects to a dictionary of their representation
        d = { '__class__':obj.__class__.__name__, 
              '__module__':obj.__module__,
              }
        #d.update(obj.__dict__)
        d.update(props(obj))
        return d


print "props",props(o)
print "encode o",MyEncoder().encode(o)
encoded_object = MyEncoder().encode(o) # '[{"d: "9", "__module__": "__main__", "__class__": "a"}]'

#myobj_instance = MyDecoder().decode(encoded_object)
#print myobj_instance

def jm(d):
    print d
    return a(d["d"])
o2= simplejson.loads(encoded_object,object_hook=jm)
print o2.A,o2.d


